package com.jthinker.blog.service.impl;

import com.jthinker.blog.bean.entity.User;
import com.jthinker.blog.bean.vo.UserWrapper;
import com.jthinker.blog.service.UserInfoService;
import com.jthinker.blog.service.UserService;
import com.jthinker.blog.util.PasswordHashUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.InvocationTargetException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

/**
 * User: Gang Chen
 * Date: 2015/8/5 19:04
 */
@Service
public class UserInfoServiceImpl implements UserInfoService
{
    private static final Logger LOGGER = LoggerFactory.getLogger(UserInfoService.class);

    private static final String SESSION_USER = "session_user";

    @Autowired
    private UserService userService;

    @Override
    public UserWrapper login(String username, String password, HttpServletRequest request)
    {
        User user = userService.findByUsername(username);
        if (user == null)
        {
            return null;
        }

        String salt = user.getSalt();
        String passHash = user.getPassword();
        String correctHash = PasswordHashUtils.contachHash(salt, passHash);

        try
        {
            if (PasswordHashUtils.validatePassword(password, correctHash))
            {
                UserWrapper wrapper = new UserWrapper();
                BeanUtils.copyProperties(wrapper, user);

                request.getSession().setAttribute(SESSION_USER, wrapper);
                LOGGER.info("{} login from {} success..", wrapper, getIpAddr(request));
                return wrapper;
            }
            else
            {
                return null;
            }
        }
        catch (NoSuchAlgorithmException e)
        {
            LOGGER.error("{}", e);
        }
        catch (InvalidKeySpecException e)
        {
            LOGGER.error("{}", e);
        }
        catch (InvocationTargetException e)
        {
            LOGGER.error("{}", e);
        }
        catch (IllegalAccessException e)
        {
            LOGGER.error("{}", e);
        }

        return null;
    }

    @Override
    public boolean logout(HttpServletRequest request)
    {
        HttpSession session = request.getSession();
        session.removeAttribute(SESSION_USER);
        session.invalidate();
        return true;
    }

    @Override
    public UserWrapper getCurrentUser(HttpServletRequest request)
    {
        Object obj = request.getSession().getAttribute(SESSION_USER);
        return obj != null ? (UserWrapper) obj : null;
    }

    @Override
    public int updatePassword(UserWrapper wrapper, String oldPassword, String newPassword)
    {
        String username = wrapper.getUsername();
        User user = userService.findByUsername(username);
        if (user == null)
        {
            return -1;
        }

        String salt = user.getSalt();
        String passHash = user.getPassword();
        String correctHash = PasswordHashUtils.contachHash(salt, passHash);

        try
        {
            if (PasswordHashUtils.validatePassword(oldPassword, correctHash))
            {
                String hash = PasswordHashUtils.createHash(newPassword);

                //获取密码HASH
                String passHash0 = PasswordHashUtils.getHash(hash);
                //获取盐
                String salt0 = PasswordHashUtils.getSalt(hash);
                user.setPassword(passHash0);
                user.setSalt(salt0);

                userService.merge(user);
                return 1;
            }
            else
            {
                return -2;
            }
        }
        catch (Exception e)
        {
            LOGGER.error("Exception", e);
            return -3;
        }
    }

    private String getIpAddr(HttpServletRequest request)
    {
        String ip = request.getHeader("X-Real-IP");
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

}
